 package cn.com.dashihui.api.service;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.stream.Collectors;

import org.apache.log4j.Logger;

import com.alipay.api.AlipayApiException;
import com.alipay.api.CertAlipayRequest;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.jfinal.aop.Before;
import com.jfinal.json.FastJson;
import com.jfinal.kit.JsonKit;
import com.jfinal.kit.PathKit;
import com.jfinal.kit.PropKit;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;
import com.jfinal.plugin.activerecord.tx.Tx;
import com.jfinal.plugin.redis.Cache;
import com.jfinal.plugin.redis.Redis;

import cn.com.dashihui.api.asyncThread.TeamFreeTask;
import cn.com.dashihui.api.common.GroupCode;
import cn.com.dashihui.api.common.OrderCode;
import cn.com.dashihui.api.common.RedisKey;
import cn.com.dashihui.api.common.SysConfig;
import cn.com.dashihui.api.dao.Goods;
import cn.com.dashihui.api.dao.OrderG;
import cn.com.dashihui.api.dao.OrderPayAPIRecord;
import cn.com.dashihui.api.dao.User;
import cn.com.dashihui.kit.CommonKit;
import cn.com.dashihui.kit.DatetimeKit;
import cn.com.dashihui.kit.DoubleKit;
import cn.com.dashihui.kit.ThreadPoolKit;
import cn.com.dashihui.pay.wx.kit.HttpsRequest;
import cn.com.dashihui.pay.wx.kit.UtilKit;
import cn.com.dashihui.pay.wx.request.RefOrderReqData;
import cn.com.dashihui.pay.wx.response.RefOrderResData;
import io.netty.util.concurrent.ThreadPerTaskExecutor;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Response;
import redis.clients.jedis.Transaction;

/**
 * 修正版团购逻辑
 * @author Administrator
 *	jedis.set( teamNum + "_" + goodsid , JsonKit.toJson(teamOrders));
	teamOrders = FastJson.getJson().parse(jedis.get( teamNum + "_" + goodsid ),List.class);
 */
public class GroupbuyingService2 {
	private static Logger logger = Logger.getLogger(GroupbuyingService2.class);
	private Cache orderCache = Redis.use();
	
	
	/**
	 * 程序入口
	 * @param order
	 */
	public void dealTeamBuy(OrderG order){
		ThreadPoolKit.teamThreadPool.execute(new TeamFreeTask(order));
	}
	
	/**
	 * 是否是免单团购
	 * @param order
	 * @return
	 */
	public void dealTeamOrder(OrderG order) {
		
		int goodsid = order.getInt("goodsid");
		//TODO  1 查找商品信息
		Goods good = Goods.me().findById(goodsid);
		System.out.println("LLLLL异步执行：查找的good商品信息"+goodsid);
		if ( good.getInt("gbmethod")==GroupCode.gbmethod.FREE ){
			//免单团
			order = dealTeamOrderG(order);
		}
		
		sureUpdate(order,0); 
	}
	/**
	 * 确保保存订单成功
	 * @param order
	 * @param count
	 */
	private void sureUpdate(OrderG order,Integer count) {
		if ( !order.update() ){
			count++;
			if ( count <3 ){
				sureUpdate(order,count);
			} else {
				logger.error("团购订单保存失败"+order);
			}
		}
	}
	
	
	/**
	 * 处理  免单的团购订单 主要业务逻辑
	 * @return
	 */
	private OrderG dealTeamOrderG(OrderG order) {
		System.out.println("LLLLL异步执行：  免单逻辑的订单："+order);
		int goodsid = order.getInt("goodsid");
		Jedis jedis = orderCache.getJedis();
		
		//TODO 1.2 判断是否有团中团号
		String teamNum = order.getStr("teamNum");
		//查找商品信息
		Goods good = Goods.me().findById(goodsid);
		int teamSize = good.getInt("gbperson") ;
		OrderG leader = null ;
		int buyNum = 0;
		if ( teamNum != null ){
			System.out.println("LLLLL异步执行： ----------------团中团逻辑-----------------------");
			System.out.println("LLLLL异步执行： ----团中团---- 团中团号："+teamNum);
			//处理团中团
			Object result = teamInTeam(order, teamNum, goodsid, good, teamSize,jedis);
			System.out.println("LLLLL异步执行： ----团中团---- 处理团中团结果："+result);
			buyNum = getBuyNum(order, goodsid, jedis); 
			order.set("buyNum", buyNum);
			System.out.println("LLLLL异步执行： ----团中团---- 大团号："+buyNum);
			if (teamNum.equals(result)){
				//  团长免单了
				//  剔除免单队列里面的团长
				String sql = "SELECT * FROM t_bus_order_gb WHERE teamNum=? AND isLeader=? ";
				leader = OrderG.me().findFirst(sql , teamNum,GroupCode.isLeader.LEADER);
				//如果 未成团 缓存有 已免单团长，那么移除他
				String key = RedisKey.Key.TEAMINTEAM + goodsid;
				dealFreeLeader(goodsid, buyNum, good, teamSize, jedis, order, leader, key);
				return order;
			} else if (result.equals("-1")){
				System.out.println("LLLLL异步执行： ----团中团---- 大团号："+buyNum);
				System.out.println("LLLLL异步执行： ----团中团---- 甩单："+order);
				//  针对甩单的订单   不参与大团进teamSize出1的原则   所以直接返回
				return order;
			}  
		}  else {
			//TODO  1.1 取出并更新大团号
			buyNum = getBuyNum(order, goodsid, jedis); 
			order.set("buyNum", buyNum);
			System.out.println("LLLLL异步执行： ------非团中团---- 大团号："+buyNum);
		}
		System.out.println("LLLLL异步执行： ------非团中团---- 处理大团逻辑：");
		//处理大团逻辑
		dealBigTeam(goodsid, buyNum, good, teamSize,jedis,order); 
		return order;
	}
	/**
	 * 处理大团逻辑
	 * @param goodsid
	 * @param buyNum
	 * @param good
	 * @param teamSize
	 */
	@SuppressWarnings("unchecked")
	private void dealBigTeam(int goodsid, int buyNum, Goods good,
			int teamSize,Jedis jedis,OrderG order) {
		List<Integer> freeList = new ArrayList<Integer>();
		int id = order.getInt("id");
		//检查teaminteam+id  存放该商品 订单未免单id集合，判断什么时候大团免单
		String key = RedisKey.Key.TEAMINTEAM + goodsid;
		
		
		if ( buyNum != 1 ){
			//监视
			jedis.watch(key);
			List<Integer> list = FastJson.getJson().parse(jedis.get( key ),List.class);
			//开启事务监听
			Transaction tx = startTx(jedis,key);
			//处理未成团拼团订单
			List<Object> exec = dealUnBeTeam(teamSize, jedis, freeList, id, key, tx, list);
			if(exec == null || exec.isEmpty() ){
				//失败   有人改动
				//重新执行
				dealBigTeam(goodsid, buyNum, good, teamSize,jedis,order); 
			}
			System.out.println("LLLLL异步执行： ------非团中团---- 进N出1结束：");
		} else {
			//首单默认成团
			order.set("teamOver", GroupCode.teamOver.YES);
		}
		
		
		//符合免单
		if ( freeList.size()>0 && freeList.size()==teamSize ) {
			//遍历  更改订单属性
			freeList.stream().forEach(re -> {
				sureSuccess(re,0);
				System.out.println("LLLLL异步执行： ------非团中团---- 更改order属性：成团成功"+re);
			});
			
			//1 找出免单人数，
			int gbFree = good.getInt("gbfreeperson");
			System.out.println("LLLLL异步执行： ------非团中团---- 免单人数"+gbFree);
			//查询数据库,查询出该商品未免单，订单状态未退款，的订单
			String sql = "SELECT * FROM t_bus_order_gb WHERE isFree=0 AND paystate=2 AND goodsid=? AND tuistate=0 AND buyNum!=0  ORDER BY buyNum ASC ";
			List<OrderG> orderList = OrderG.me().find(sql, goodsid);
			
			orderList = orderList.stream().limit(5).sorted((p1,p2)->p1.getInt("buyNum").compareTo(p2.getInt("buyNum"))).collect(Collectors.toList());
			System.out.println("LLLLL异步执行： ------非团中团---- 需免单的订单"+orderList);
			if(orderList.size()>0&&orderList!=null){
				//需要免单的订单
				for(int i=0;i<gbFree;i++){
					System.out.println("LLLLL异步执行： ------非团中团---- 需免单的订单"+orderList.get(i).getInt("buyNum"));
					System.out.println("LLLLL异步执行： ------非团中团---- 需免单的订单"+orderList.get(i).getInt("BUYNUM"));
					orderFree(orderList.get(i),2);
				}
			}else{
				//查询失败  TODO 
				logger.error("查询团队异常---");
			}
		}
	}
	/**
	 * 处理未成团拼团订单逻辑
	 * @param teamSize
	 * @param jedis
	 * @param freeList
	 * @param id
	 * @param key
	 * @param tx
	 * @param list
	 * @return
	 */
	private List<Object> dealUnBeTeam(int teamSize, Jedis jedis, List<Integer> freeList,
			int id, String key,
			Transaction tx, List<Integer> list) {
		System.out.println("LLLLL异步执行： ------非团中团---- 成团数组（大团进N出1）："+list);
		if ( list==null ){
			list = new ArrayList<Integer>();
			list.add( id );
			System.out.println("LLLLL异步执行： ------非团中团---- 首次生成成团数组并添加："+list);
		} else if ( list.size() == teamSize ){
			System.out.println("LLLLL异步执行： ------非团中团---- 满员："+list);
			//提示免单
			freeList.addAll(list);
			System.out.println("LLLLL异步执行： ------非团中团---- 清空成团数组：");
			list.clear();
			list.add( id );
			System.out.println("LLLLL异步执行： ------非团中团---- 把自己加进去："+list);
		} else if( list.size() == (teamSize-1) ){
			System.out.println("LLLLL异步执行： ------非团中团---- 差自己满员："+list);
			if ( !list.contains( id ) ) {
				list.add( id );
			}
			System.out.println("LLLLL异步执行： ------非团中团---- 把自己加进去："+list);
			freeList.addAll(list);
			list.clear();
			System.out.println("LLLLL异步执行： ------非团中团---- 成团清空："+list);
			
		} else {
			System.out.println("LLLLL异步执行： ------非团中团---- 差好多满员："+list);
			if ( !list.contains( id ) )
			list.add( id );
		}
		tx.set( key ,JsonKit.toJson(list));
		//提交并释放
		List<Object> exec = commAndReset(jedis, tx);
		return exec;
	}
	/**
	 * 移除  未成团缓存  中的团长
	 * @param goodsid
	 * @param buyNum
	 * @param good
	 * @param teamSize
	 * @param jedis
	 * @param order
	 * @param leader
	 * @param key
	 */
	@SuppressWarnings("unchecked")
	private void dealFreeLeader(int goodsid, int buyNum, Goods good,
			int teamSize, Jedis jedis, OrderG order,
			OrderG leader, String key) {
		jedis.watch(key);
		List<Integer> list = FastJson.getJson().parse(jedis.get( key ),List.class);
		//开启事务监听
		Transaction tx = startTx(jedis,key);
		
		System.out.println("LLLLL异步执行： ------非团中团---- 大团成团免单的数组元素："+list);
		//删除免单的队长
		if ( list!=null && list.contains(leader.getInt("id")) ){
			for (int i=0;i<list.size();i++){
				if( list.get(i) == leader.getInt("id") ){
					list.remove(i);
				}
			}
		}
		tx.set( key ,JsonKit.toJson(list));
		//提交并释放
		List<Object> exec = commAndReset(jedis, tx);
		if(exec == null || exec.isEmpty() ){
			//失败   有人改动
			//重新执行
			dealBigTeam(goodsid, buyNum, good, teamSize,jedis,order); 
		}
		System.out.println("LLLLL异步执行： ------非团中团---- 移除免单的团长："+leader);
	}
	/**
	 * 大团进二免一成功，需要更改 两个订单的属性
	 * @param re
	 * @param count
	 */
	private  void  sureSuccess(Integer re,Integer count) {
		if (Db.update("UPDATE t_bus_order_gb SET teamOver=? WHERE id=? ",GroupCode.teamOver.YES, re)!=1){
			if ( count < 3 ){
				count++;
				sureSuccess(re,count);
			} else {
				logger.error("更改团购商品："+re+"---成团字段teamOver->更改失败");
			}
		} 
	}
	
	
	/**
	 * 获取大团号
	 * @param order
	 * @param key
	 * @param jedis
	 * @return
	 */
	private int getBuyNum(OrderG order, int goodsid, Jedis jedis) {
		String key = RedisKey.Key.TEAM + goodsid;
		int buyNum = 1;
		jedis.watch(key);
		String num = jedis.get(key);
		//开启事务监听
		Transaction tx = startTx(jedis,key);
		//主要逻辑
		if ( num==null ){
			//如果是开团   设置为1
			tx.set(key, buyNum+"");
		} else {
			//如果不是开团   设置大团号+1
			buyNum = Integer.parseInt(num)+1;
			tx.set(key, buyNum+"");
		}
		
		//提交并获取结果，结束监听
		List<Object> exec = commAndReset(jedis, tx);
		if(exec == null || exec.isEmpty() ){
			//失败   有人改动
			//重新执行
			getBuyNum(order,goodsid,jedis);
		}
		return buyNum;
	}
	/**
	 * 提交并释放监视
	 * @param jedis
	 * @param tx
	 * @return
	 */
	private List<Object> commAndReset(Jedis jedis, Transaction tx) {
		//提交事务
		List<Object> exec = tx.exec();
		//释放
		jedis.resetState();
		jedis.unwatch();
		return exec;
	}
	/**
	 * 开启  监视事务
	 * @param jedis
	 */
	private Transaction startTx(Jedis jedis,String str) {
		
		//开启事务
		Transaction tx = jedis.multi();
		return tx;
	}

	/**
	 * 处理团中团免单相关业务
	 * @param order
	 * @param teamNum
	 * @param goodsid
	 * @param good
	 * @param teamSize
	 */
	private Object teamInTeam(OrderG order, String teamNum,
			int goodsid, Goods good, int teamSize,Jedis jedis) {
		// TODO 3.1 查看是否是团长
		if ( order.getInt("isLeader") == GroupCode.isLeader.LEADER ) {
			
			//3.1.1  是团长
			//开启redis的list
			List<Integer> list = new ArrayList<Integer>();
			jedis.set(teamNum+RedisKey.Key.TEAMSIZE+goodsid,JsonKit.toJson(list));
			System.out.println("LLLLL异步执行： ----团中团---- 是团长：开启小分队（不包含团长）--teamNum+RedisKey.Key.TEAMSIZE+goodsid"+list);
			return "1";
			
		} else {
			System.out.println("LLLLL异步执行： ----团中团---- 不是团长：");
			//3.1.2 团员
			//找出  该团 已付款 未退款 的队长  
			String sql = "SELECT * FROM t_bus_order_gb WHERE teamNum=? AND isLeader=? AND payState=? "
					+ " AND isFree=?   ";
			OrderG leader = OrderG.me().findFirst(sql,teamNum,GroupCode.isLeader.LEADER,OrderCode.OrderPayState.HAD_PAY,0);
			if ( leader != null ){
				System.out.println("LLLLL异步执行： ----团中团---- 找出团长："+leader);
				//3.1.2 有效  团中团
				return hadTeam(order, teamNum, goodsid,  teamSize, jedis, leader);
			} else {
				System.out.println("LLLLL异步执行： ----团中团---- 找不出团长：甩大团"+leader);
				//3.1.3 无效团中团   清除团中团号  甩大团（不参与进二出一）
				order.set("teamNum", null);
				return "-1";
			}
		}
		
		
		
	}

	/**
	 * 有效团中团逻辑
	 * @param order
	 * @param teamNum
	 * @param goodsid
	 * @param good
	 * @param teamSize
	 * @param jedis
	 * @param leader
	 * @return
	 */
	@SuppressWarnings("unchecked")
	private Object hadTeam(OrderG order, String teamNum, int goodsid, 
			int teamSize, Jedis jedis,OrderG leader) {
		String key = teamNum+RedisKey.Key.TEAMSIZE+goodsid;
		jedis.watch(key);
		List<Integer> list = FastJson.getJson().parse(jedis.get( key  ),List.class);
		System.out.println("LLLLL异步执行： ----团中团---- 找出小分队："+list);
		if ( list !=null ){
			//存在 
			int count = list.size();
			if ( count == teamSize ){
				//满员  成团免单  清除团中团号    拼单  删除
				order.set("teamNum", null);
				jedis.del( key );
				System.out.println("LLLLL异步执行： ----团中团---- 小分队满员：删除小分队，order拼单去："+order);
				return "1";
			}  else {
				// 把自己id加进去
				list.add(order.getInt("id"));
				Transaction tx = startTx(jedis, key );
				tx.set(key,JsonKit.toJson(list));
				List<Object> exec = commAndReset(jedis,  tx);
				if(exec == null || exec.isEmpty() ){
					//失败   有人改动
					//重新执行
					return hadTeam(order,teamNum,goodsid,teamSize,jedis,leader);
				}
				System.out.println("LLLLL异步执行： ----团中团---- 加入小分队："+list);
				//赠送团长积分
				giveSppointByTeamNum( leader);
				System.out.println("LLLLL异步执行： ----团中团---- 赠送给团长积分奖励："+leader);
				if ( count == (teamSize-1)){
					System.out.println("LLLLL异步执行： ----团中团---- 加入小分队后小分队满员："+list);
					//差一位  TODO    免单队长   甩单
					orderFree(  leader , 1 );
					jedis.del( key );
					System.out.println("LLLLL异步执行： ----团中团---- 加入小分队后小分队满员：免单团长"+leader);
					return teamNum;
				} 
				return "-1";
			}
		} else {
			
			//不存在
			int teamOver = leader.getInt("teamOver");
			
			// 清除团中团号
			order.set("teamNum", null);
			if (teamOver==GroupCode.teamOver.YES){
				System.out.println("LLLLL异步执行： ----团中团---- 小分队不存在：团长成团免单了，拼单去吧");
				//成团免单     拼单
				return "1";
			} else {
				System.out.println("LLLLL异步执行： ----团中团---- 小分队不存在：提前免单了，甩大团");
				//未成团失效     甩大团（不参与进二出一）
				return "-1";
			}
		}
	}
	
	/**
	 * 免单
	 * @param certpath
	 * @param certpassword
	 * @param orderfree
	 */
	private void orderFree( OrderG orderfree ,int type ) {
		String certpath = PathKit.getRootClassPath()+"/"+PropKit.get("weixinpay.open.cert");
		String certpassword = PropKit.get("weixinpay.mch_id");
		orderfree.set("isFree", GroupCode.isFree.NEEDFREE);
		//退款
		if(orderfree.update()){
			//如果已更改为需免单，那么执行退款，并更改isFree状态以及记录t_bus_order_gb_log日志
			int paytype = orderfree.getInt("paytype");
			if(paytype==OrderCode.OrderPayMethod.ALIPAY){
				//付款方式为支付宝的退款
				System.out.println(">>>>>>>>>>>付款方式为   支付宝   的退款<<<<<<<<<<<<<<");
				//支付宝
				String gateway=PropKit.get("applipay.url");
				String app_id=PropKit.get("appalipay.partner");
				String privateKey=PropKit.get("appalipay.privateKey");
				String charset=PropKit.get("applipay.charset");
				String sign_type=PropKit.get("applipay.signType");
				String app_cert_path=PathKit.getRootClassPath()+"/"+PropKit.get("applipay.appCertPublicKey");
				String alipay_cert_path=PathKit.getRootClassPath()+"/"+PropKit.get("applipay.alipayCertPublicKey");
				String alipay_root_cert_path=PathKit.getRootClassPath()+"/"+PropKit.get("applipay.alipayRootCert");
				//构造client
				CertAlipayRequest certAlipayRequest = new CertAlipayRequest();
				certAlipayRequest.setServerUrl(gateway);
				certAlipayRequest.setAppId(app_id);
				certAlipayRequest.setPrivateKey(privateKey);
				certAlipayRequest.setFormat("json");
				certAlipayRequest.setCharset(charset);
				certAlipayRequest.setSignType(sign_type);
				certAlipayRequest.setCertPath(app_cert_path);
				certAlipayRequest.setAlipayPublicCertPath(alipay_cert_path);
				certAlipayRequest.setRootCertPath(alipay_root_cert_path);
				String orderNum=orderfree.getStr("orderNum");
				String out_refund_no = "TT"+DatetimeKit.getFormatDate("yyyyMMddHHmmssSSS")+CommonKit.randomNum(3);
				String total_fee = String.valueOf(Double.valueOf(orderfree.getDouble("amount")));
				DefaultAlipayClient alipayClient;
				try {
					alipayClient = new DefaultAlipayClient(certAlipayRequest);
					AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();//创建API对应的request类
					request.setBizContent("{" +
					"    \"out_trade_no\":\""+orderNum+"\"," +
					"    \"refund_reason\":\"免单退款\"," +
					"    \"refund_amount\":\""+total_fee+"\"" +
					
					"  }");//设置业务参数
					AlipayTradeRefundResponse response = alipayClient.certificateExecute(request);//通过alipayClient调用API，获得对应的response类
					System.out.print("支付宝退款请求响应："+response.getBody());
					if (response.isSuccess()) {//请求成功
						System.out.println("支付宝退款请求成功");
						//保存接口请求记录
						new OrderPayAPIRecord().set("orderNum", orderNum)
						.set("sendContent", request.getBizContent())
						.set("returnContent", response.getBody())
							.set("payMethod", paytype)
							.set("flag", 4)
							.save();
						if("Success".equals(response.getMsg())){
							System.out.println("支付宝退款成功");
							if(type == 1){
								orderfree.set("teamOver", GroupCode.teamOver.YES).set("isFree", GroupCode.isFree.BACKED);
							} else {
								orderfree.set("isFree", GroupCode.isFree.BACKED);
							}
							//更新订单免单退款状态为已免单
							if(!orderfree.update()){
								//更改订单为   已免单 状态失败 
								Record re = new Record();
								re.set("orderNum", orderfree.getStr("orderNum"))
								  .set("type",GroupCode.exceptionType.UPDATE_GB_REFUND_FAILED)
								  .set("user",orderfree.getInt("userid"));
								if ( type == 1 ) {
									re.set("action",GroupCode.exceptionType.UPDATE_GBFREEPERSON_FAILED_ACTION_TEAM)
									  .set("content",GroupCode.exceptionType.UPDATE_GB_REFUND_FAILED_CONTENT_TEAM);
								}  else {
									re.set("action",GroupCode.exceptionType.UPDATE_GBFREEPERSON_FAILED_ACTION)
									  .set("content",GroupCode.exceptionType.UPDATE_GB_REFUND_FAILED_CONTENT);
								}
								if(!Db.save("t_bus_order_exception_log", re)){
									if ( type == 1 ) {
										logger.error("需要 团中团 支付宝免单异常，订单号："+orderfree.getStr("orderNum"));
									}else {
										logger.error("需要支付宝免单异常，订单号："+orderfree.getStr("orderNum"));
									}
								}
							}
						}
					}else {
						//发送退款请求失败
						//发送退款请求失败
						Record re = new Record();
						re.set("orderNum", orderfree.getStr("orderNum"))
						  .set("refundNum",out_refund_no)
						  .set("type",GroupCode.exceptionType.GB_ZFB_SEND_REQ_FAILED)
						  .set("user",orderfree.getInt("userid"));
						  if ( type == 1 ) {
								re.set("action",GroupCode.exceptionType.GB_ZFB_SEND_REQ_FAILED_ACTION_TEAM)
								  .set("content",GroupCode.exceptionType.GB_ZFB_SEND_REQ_FAILED_CONTENT_TEAM);
							}  else {
								re.set("action",GroupCode.exceptionType.GB_ZFB_SEND_REQ_FAILED_ACTION)
								  .set("content",GroupCode.exceptionType.GB_ZFB_SEND_REQ_FAILED_CONTENT);
							}
						if(!Db.save("t_bus_order_exception_log", re)){
							if ( type == 1 ) {
								logger.error("支付宝团中团退款异常，订单号："+orderfree.getStr("orderNum"));
							} else {
								logger.error("支付宝大团退款异常，订单号："+orderfree.getStr("orderNum"));
							}
						}
					}
				} catch (AlipayApiException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					//发送准备退款请求失败
					Record re = new Record();
					re.set("orderNum", orderfree.getStr("orderNum"))
					  .set("refundNum",out_refund_no)
					  .set("type",GroupCode.exceptionType.GB_ZFB_SEND_REQ_FAILED)
					  .set("user",orderfree.getInt("userid"));
					  if ( type == 1 ) {
							re.set("action",GroupCode.exceptionType.GB_ZFB_SEND_REQ_FAILED_ACTION_TEAM)
							  .set("content",GroupCode.exceptionType.GB_ZFB_SEND_REQ_FAILED_CONTENT_TEAM);
						}  else {
							re.set("action",GroupCode.exceptionType.GB_ZFB_SEND_REQ_FAILED_ACTION)
							  .set("content",GroupCode.exceptionType.GB_ZFB_SEND_REQ_FAILED_CONTENT);
						}
					if(!Db.save("t_bus_order_exception_log", re)){
						if ( type == 1 ) {
							logger.error("支付宝团中团退款异常，订单号："+orderfree.getStr("orderNum"));
						} else {
							logger.error("支付宝大团退款异常，订单号："+orderfree.getStr("orderNum"));
						}
					}
				}
				
				
				
				
			}else if(paytype==OrderCode.OrderPayMethod.WEIXIN){
				//付款方式为微信的退款
				System.out.println(">>>>>>>>>>>付款方式为   微信   的退款<<<<<<<<<<<<<<");
				//付款方式为微信的退款
				String orderNum = orderfree.getStr("orderNum");
				String out_refund_no = "TT"+DatetimeKit.getFormatDate("yyyyMMddHHmmssSSS")+CommonKit.randomNum(3);
				String total_fee = String.valueOf(Double.valueOf(DoubleKit.mul(orderfree.getDouble("amount"),100)).intValue()).toString();
				//向微信发起退款请求
				RefOrderReqData reOrderReqData = new RefOrderReqData(orderNum,out_refund_no,total_fee,total_fee, "免单退款");
				RefOrderResData reOrderRspData = null;
				try {
					reOrderRspData = (RefOrderResData)UtilKit.getObjectFromXML(new HttpsRequest(certpath,certpassword).post(PropKit.get("weixinpay.orderrefund"), reOrderReqData), RefOrderResData.class);
				}catch(Exception e){
					//发送退款请求失败
					Record re = new Record();
					re.set("orderNum", orderfree.getStr("orderNum"))
					  .set("refundNum",out_refund_no)
					  .set("type",GroupCode.exceptionType.GB_WX_SEND_REQ_FAILED)
					  .set("user",orderfree.getInt("userid"));
					  
					if ( type == 1 ) {
						re.set("action",GroupCode.exceptionType.GB_WX_SEND_REQ_FAILED_ACTION_TEAM)
						  .set("content",GroupCode.exceptionType.GB_WX_SEND_REQ_FAILED_CONTENT_TEAM);
					}  else {
						re.set("action",GroupCode.exceptionType.GB_WX_SEND_REQ_FAILED_ACTION)
						  .set("content",GroupCode.exceptionType.GB_WX_SEND_REQ_FAILED_CONTENT);
					}
					
					if(!Db.save("t_bus_order_exception_log", re)){
						if ( type == 1 ) {
							logger.error("微信团中团退款异常，订单号："+orderfree.getStr("orderNum"));
						} else {
							logger.error("微信退款异常，订单号："+orderfree.getStr("orderNum"));
						}
						
					}
				}
				//预支付完成
				if(reOrderRspData!=null){
					System.out.println("Response....:"+reOrderReqData);
					//保存接口请求记录
					String sendContent = UtilKit.getXMLFromObject(reOrderReqData);
					String returnContent = UtilKit.getXMLFromObject(reOrderRspData);
					new OrderPayAPIRecord().set("orderNum", orderNum)
						.set("sendContent", sendContent)
						.set("returnContent", returnContent)
						.set("payMethod", paytype)
						.set("flag", 4)
						.save();
					if(reOrderRspData.getReturn_code().equals("SUCCESS")&&reOrderRspData.getResult_code().equals("SUCCESS")){
						
						
						
						//注意！！！！！！！！！！！！！！！！！！！！！！！！   还需要设置字段
						//更新订单免单退款状态为退款中。。。   
						
						
						
						if(type == 1){
							orderfree.set("teamOver", GroupCode.teamOver.YES).set("isFree", GroupCode.isFree.BACKING);
						} else {
							orderfree.set("isFree", GroupCode.isFree.BACKING);
						}
						
						if(!orderfree.update()){
							//更改订单为   退款中 状态失败 
							Record re = new Record();
							re.set("orderNum", orderfree.getStr("orderNum"))
							  .set("type",GroupCode.exceptionType.UPDATE_GB_REFUNDING_FAILED)
							  .set("user",orderfree.getInt("userid"));
							if ( type == 1 ) {
								 re.set("action",GroupCode.exceptionType.UPDATE_GBFREEPERSON_FAILED_ACTION_TEAM)
								  .set("content",GroupCode.exceptionType.UPDATE_GB_REFUNDING_FAILED_CONTENT_TEAM);
							}else {
								 re.set("action",GroupCode.exceptionType.UPDATE_GBFREEPERSON_FAILED_ACTION)
								  .set("content",GroupCode.exceptionType.UPDATE_GB_REFUNDING_FAILED_CONTENT);
							}
							 
							if(!Db.save("t_bus_order_exception_log", re)){
								if ( type == 1 ) {
									logger.error("需要 团中团 免单异常，订单号："+orderfree.getStr("orderNum"));
								}else {
									logger.error("需要免单异常，订单号："+orderfree.getStr("orderNum"));
								}
							}
						}
					}
				}
			}else if (paytype==OrderCode.OrderPayMethod.BALANCE1) {
				try {
					orderFreeMoney(orderfree, type);
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}else{
			//更改订单失败状态失败 
			Record re = new Record();
			re.set("orderNum", orderfree.getStr("orderNum"))
			  .set("type",GroupCode.exceptionType.UPDATE_GBFREEPERSON_FAILED)
			  .set("user",orderfree.getInt("userid"));
			if ( type == 1) {
				re.set("action",GroupCode.exceptionType.UPDATE_GBFREEPERSON_FAILED_ACTION_TEAM)
				  .set("content",GroupCode.exceptionType.UPDATE_GBFREEPERSON_FAILED_CONTENT_TEAM);
			} else {
				re.set("action",GroupCode.exceptionType.UPDATE_GBFREEPERSON_FAILED_ACTION)
				  .set("content",GroupCode.exceptionType.UPDATE_GBFREEPERSON_FAILED_CONTENT);
			}
			
			if(!Db.save("t_bus_order_exception_log", re)){
				if ( type == 1) {
					
					logger.error("团中团需要免单异常，订单号："+orderfree.getStr("orderNum"));
				} else {
					logger.error("   需要免单异常，订单号："+orderfree.getStr("orderNum"));
				}
				
			}
		}
		
	}
	
	/**
	 * 团购结束的业务
	 * 获取百分比
	 * 获取订单价格
	 * 获取更该用户积分  并记录
	 * @param good
	 */
	public  void groupBuyOver(int id){
		//抵扣券
		Double gjkpoint = 0.00;
		//积分
		Double gsppoint = 0.00;
		try {
			gjkpoint = SysConfig.getGroupDownGiveD();
			gsppoint = SysConfig.getGroupDownGiveJ();
		} catch (Exception e) {
			logger.error("获取配制参数有误，团购结束券币赠送失败");
		}
		//找出已支付   未免单  的
		String sql = "SELECT * FROM t_bus_order_gb WHERE payState=? AND isFree=? AND goodsid=? AND iscompensated=? ";
		
		List<OrderG> find = OrderG.me().find(sql,OrderCode.OrderPayState.HAD_PAY,0,id,0);
		if ( find!=null && find.size()>0 ){
			Double njkpoint = gjkpoint;
			Double nsppoint = gsppoint;
			
			
			find.stream().forEach(order->{
				System.out.println("团购结束送积分啦~！~~~~~~~~~~~~~~~~~~~~");
				//设置订单为已补偿
				order.set("iscompensated", 1).update();
				//送积分补偿
				giveUserCompensation(njkpoint, nsppoint, order);
			});
		}
		
		
	}
	/**
	 * 团购结束用户补偿
	 * @param njkpoint  需要补偿的抵扣券百分比
	 * @param nsppoint	需要补偿的积分百分比
	 * @param order	订单
	 */
	private  void giveUserCompensation(Double njkpoint, Double nsppoint, OrderG order) {
		int userid = order.getInt("userid");
		User user = User.me().findById(userid);
		Double ojkpoint = user.getDouble("jkpoint");
		Double osppoint = user.getDouble("sppoint");
		Double amount = order.getDouble("amount");
		//需要变化的券值
		Double jkpoint = DoubleKit.mul(amount, njkpoint);
		Double sppoint = DoubleKit.mul(amount, nsppoint);
		Double nowjkpoint = DoubleKit.add(jkpoint, ojkpoint);
		Double nowsppoint = DoubleKit.add(sppoint, osppoint);
		String sqll = "UPDATE t_bus_user SET sppoint=? , jkpoint=? WHERE id=? AND sppoint=? AND jkpoint=? ";
		if ( Db.update(sqll,nowsppoint,nowjkpoint,userid,osppoint,ojkpoint)!=1 ){
			giveUserCompensation(njkpoint, nsppoint, order);
		}
		Record record = new Record();
		record.set("type", 1)
			  .set("flag", 18)
			  .set("fromOrderNum", order.getStr("orderNum"))
			  .set("orderMoney", amount)
			  .set("userid", userid)
			  .set("sppoint", sppoint)
			  .set("sppointHistory", sppoint)
			  .set("dedu",jkpoint)
			  .set("deduHistory",ojkpoint)
			  .set("describe", "团购结束未免单补偿")
			  .set("createDate", new Date());
		if ( !Db.save("t_bus_user_value_log", record) ){ 
			logger.error("团购结束送积分业务：用户积分变化记录失败=》"+record);
		}
	}
	
	
	
	
	/**
	 * 赠送邀请积分
	 * @param order
	 */
	public void giveSppointByTeamNum(OrderG order) {
		String sql = "SELECT tu.id,tu.sppoint FROM t_bus_order_gb tg "
				+ "LEFT JOIN t_bus_user tu ON tg.userid=tu.id "
				+ "WHERE tg.teamNum=? AND isLeader=? ";
		Record re = Db.findFirst(sql,order.getStr("teamNum"),GroupCode.isLeader.LEADER);
		if(re!=null){
			Double sppoint = re.getDouble("sppoint");
			//准备数据
			//奖励积分
			Double sppoints = 0.00;
			try {
				sppoints = SysConfig.getGroupSppoint();
			} catch (Exception e) {
				
			}
			Double newsppoint = DoubleKit.add(sppoint, sppoints);
			Db.update("UPDATE t_bus_user SET sppoint=? WHERE id=?",newsppoint,re.getInt("id"));
			
			Record record = new Record();
			record.set("type", 1)
				  .set("flag", 11)
				  .set("fromOrderNum", order.getStr("orderNum"))
				  .set("orderMoney", order.getDouble("amount"))
				  .set("userid", order.getInt("userid"))
				  .set("sppoint", sppoints)
				  .set("sppointHistory", sppoint)
				  .set("describe", "团购邀请赠送积分")
				  .set("createDate", new Date());
			Db.save("t_bus_user_value_log", record);	  
		}
	}
	
	/**
	 * 余额免单
	 * @param orderfree
	 * @param type
	 * @throws Exception 
	 */
	@Before(Tx.class)
	public void orderFreeMoney(OrderG orderfree,int type) throws Exception {
		String out_refund_no = "TT"+DatetimeKit.getFormatDate("yyyyMMddHHmmssSSS")+CommonKit.randomNum(3);
		int userid = orderfree.getInt("userid");
		User user = User.me().findById(userid);
		//变化前金额
		Double oldMoney = user.getDouble("money");
		//增加的金额
		Double addMoney = orderfree.getDouble("amount");
		//变化后金额
		Double newMoney = DoubleKit.add(oldMoney, addMoney);
		
		Record re1 = new Record().set("userid", userid)
				.set("amount", addMoney)
				.set("type", "1")
				.set("fromOrderNum", orderfree.getStr("orderNum"))
				.set("createDate", new Date())
				.set("orderType", OrderCode.MoneyState.GOODORDER)
				.set("nowAmount", newMoney)
				.set("oldAmount", oldMoney)
				.set("describe", "团购免单退款");
		if(Db.update("UPDATE t_bus_user SET money = ? WHERE id = ?", newMoney,userid)==1){
			if(Db.save("t_bus_user_money", re1)){
					if(Db.update("INSERT INTO t_bus_order_log(orderNum,type,user,action,content) VALUES(?,?,?,?,?)",orderfree.getStr("orderNum"),OrderCode.OrderLogType.FREE,"用户",OrderCode.OrderLogType.FREE_ACTION,"团购免单退款-余额")==1){
						if(type == 1){
							orderfree.set("teamOver", GroupCode.teamOver.YES).set("isFree", GroupCode.isFree.BACKED);
						} else {
							orderfree.set("isFree", GroupCode.isFree.BACKED);
						}
						//更新订单免单退款状态为已免单
						if(!orderfree.update()){
							//更改订单为   已免单 状态失败 
							Record re = new Record();
							re.set("orderNum", orderfree.getStr("orderNum"))
							  .set("type",GroupCode.exceptionType.UPDATE_GB_REFUNDUSERMONEY_FAILED)
							  .set("user",orderfree.getInt("userid"));
							if ( type == 1 ) {
								re.set("action",GroupCode.exceptionType.UPDATE_GBFREEPERSON_FAILED_ACTION_TEAM)
								  .set("content",GroupCode.exceptionType.UPDATE_GB_REFUND_FAILED_CONTENT_TEAM);
							}  else {
								re.set("action",GroupCode.exceptionType.UPDATE_GBFREEPERSON_FAILED_ACTION)
								  .set("content",GroupCode.exceptionType.UPDATE_GB_REFUND_FAILED_CONTENT);
							}
							if(!Db.save("t_bus_order_exception_log", re)){
								if ( type == 1 ) {
									logger.error("需要 团中团 余额免单异常，订单号："+orderfree.getStr("orderNum"));
								}else {
									logger.error("需要余额免单异常，订单号："+orderfree.getStr("orderNum"));
								}
							}
						}
						return;
					}else {
						Record re = new Record();
						re.set("orderNum", orderfree.getStr("orderNum"))
						  .set("refundNum",out_refund_no)
						  .set("type",GroupCode.exceptionType.UPDATE_GB_REFUNDUSERMONEY_FAILED)
						  .set("user",orderfree.getInt("userid"));
						  
						if ( type == 1 ) {
							re.set("action",GroupCode.exceptionType.GB_ORDERLOG_FAILED_ACTION_TEAM)
							  .set("content",GroupCode.exceptionType.GB_ORDERLOG_FAILED_CONTENT_TEAM);
						}  else {
							re.set("action",GroupCode.exceptionType.GB_ORDERLOG_FAILED_ACTION)
							  .set("content",GroupCode.exceptionType.GB_ORDERLOG_FAILED_CONTENT);
						}
						
						if(!Db.save("t_bus_order_exception_log", re)){
							if ( type == 1 ) {
								logger.error("余额团中团退款异常，订单号："+orderfree.getStr("orderNum"));
							} else {
								logger.error("余额退款异常，订单号："+orderfree.getStr("orderNum"));
							}
							
						}
					}
					throw new Exception("订单日志记录失败");
			}else {
				Record re = new Record();
				re.set("orderNum", orderfree.getStr("orderNum"))
				  .set("refundNum",out_refund_no)
				  .set("type",GroupCode.exceptionType.UPDATE_GB_REFUNDUSERMONEY_FAILED)
				  .set("user",orderfree.getInt("userid"));
				  
				if ( type == 1 ) {
					re.set("action",GroupCode.exceptionType.GB_MONEYLOG_FAILED_ACTION_TEAM)
					  .set("content",GroupCode.exceptionType.GB_MONEYLOG_FAILED_CONTENT_TEAM);
				}  else {
					re.set("action",GroupCode.exceptionType.GB_MONEYLOG_FAILED_ACTION)
					  .set("content",GroupCode.exceptionType.GB_MONEYLOG_FAILED_CONTENT);
				}
				
				if(!Db.save("t_bus_order_exception_log", re)){
					if ( type == 1 ) {
						logger.error("余额团中团退款异常，订单号："+orderfree.getStr("orderNum"));
					} else {
						logger.error("余额退款异常，订单号："+orderfree.getStr("orderNum"));
					}
					
				}
			}
			throw new RuntimeException("记录money变化表失败"); 
		}else {
			Record re = new Record();
			re.set("orderNum", orderfree.getStr("orderNum"))
			  .set("refundNum",out_refund_no)
			  .set("type",GroupCode.exceptionType.UPDATE_GB_REFUNDUSERMONEY_FAILED)
			  .set("user",orderfree.getInt("userid"));
			  
			if ( type == 1 ) {
				re.set("action",GroupCode.exceptionType.GB_MONEY_FAILED_ACTION_TEAM)
				  .set("content",GroupCode.exceptionType.GB_MONEY_FAILED_CONTENT_TEAM);
			}  else {
				re.set("action",GroupCode.exceptionType.GB_MONEY_FAILED_ACTION)
				  .set("content",GroupCode.exceptionType.GB_MONEY_FAILED_CONTENT);
			}
			
			if(!Db.save("t_bus_order_exception_log", re)){
				if ( type == 1 ) {
					logger.error("余额团中团退款异常，订单号："+orderfree.getStr("orderNum"));
				} else {
					logger.error("余额退款异常，订单号："+orderfree.getStr("orderNum"));
				}
				
			}
			throw new RuntimeException("免单退款更改用户余额失败");
		}

	}
}
